#include "stdafx.h"
#include "BattleGround.h"
#include "MemTrack.h"

namespace bs
{
	const COLORREF DEFAULT_SPACE_COLOR = RGB(255, 192, 192);
	const COLORREF DEFAULT_CUR_GRID_COLOR = RGB(0, 0, 220);
	const COLORREF DEFAULT_CUR_ACTOR_COLOR = RGB(255, 20, 20);
	const COLORREF DEFAULT_MOVEABLE_COLOR = RGB(0, 255, 0);
	const COLORREF DEFAULT_ATTACKABLE_COLOR = RGB(255, 0, 0);
	const COLORREF DEFAULT_PLACEABLE_COLOR = RGB(255, 0, 0);

	BattleGround::BattleGround()
		: row(0), col(0), cellWidth(0), cellHeight(0), space(0), showCurPos(false),
		typeToShow(GT_CUR_ACTOR), curGrid(0, 0), curActorGrid(0, 0)
	{
		this->spaceBr = ::CreateSolidBrush(DEFAULT_SPACE_COLOR);
		this->curGridBr = ::CreateSolidBrush(DEFAULT_CUR_GRID_COLOR);
		this->curActorBr = ::CreateSolidBrush(DEFAULT_CUR_ACTOR_COLOR);
		this->moveableBr = ::CreateSolidBrush(DEFAULT_MOVEABLE_COLOR);
		this->attackableBr = ::CreateSolidBrush(DEFAULT_ATTACKABLE_COLOR);
		this->placeableBr = ::CreateSolidBrush(DEFAULT_PLACEABLE_COLOR);
	}

	BattleGround::~BattleGround()
	{
		::DeleteObject(this->spaceBr);
		::DeleteObject(this->curGridBr);
		::DeleteObject(this->curActorBr);
		::DeleteObject(this->moveableBr);
		::DeleteObject(this->attackableBr);
		::DeleteObject(this->placeableBr);
	}

	void BattleGround::Init( int _row, int _col, int _cellWidth, int _cellHeight, int _space )
	{
		assert("BattleGround::Init" && _row>0 && _col>0 && _cellWidth>0 && _cellHeight>0 && _space>0);

		this->row = _row;
		this->col = _col;
		this->cellWidth  = _cellWidth;
		this->cellHeight = _cellHeight;
		this->space = _space;

		this->cells.resize(this->row * this->col, 0);
	}

	void BattleGround::Draw( HDC dc )
	{
		this->DrawSpace(dc);

		if(this->showCurPos)
		{
			this->DrawCurGrid(dc);
		}

		if(this->typeToShow == GT_CUR_ACTOR)
		{
			this->DrawCurActorGrid(dc);
		}
		else if(this->typeToShow == GT_MOVEABLE)
		{
			this->DrawMoveableGrid(dc);
		}
		else if(this->typeToShow == GT_ATTACKABLE)
		{
			this->DrawAttackableGrid(dc);
		}
		else if(this->typeToShow == GT_PLACEABLE)
		{
			this->DrawPlaceabelGrid(dc);
		}
	}

	Actor* BattleGround::GetActor(int x, int y)
	{
		if(x<0 || x>=this->col || y<0 || y>=this->row)
			return NULL;

		return this->cells[x+this->col*y];
	}

	void BattleGround::SetActor(Actor* actor, Point pos)
	{
		if(pos.x<0 || pos.x>=this->col || pos.y<0 || pos.y>=this->row)
			return;

		this->cells[pos.x+this->col*pos.y] = actor;
	}

	void BattleGround::RemoveActor(Point pos)
	{
		if(pos.x<0 || pos.x>=this->col || pos.y<0 || pos.y>=this->row)
			return;

		this->cells[pos.x+this->col*pos.y] = NULL;
	}

	void BattleGround::SetSpaceColor( COLORREF color )
	{
		::DeleteObject(this->spaceBr);
		this->spaceBr = ::CreateSolidBrush(color);
	}

	void BattleGround::SetCurGridColor( COLORREF color )
	{
		::DeleteObject(this->curGridBr);
		this->curGridBr = ::CreateSolidBrush(color);
	}

	void BattleGround::SetCurActorColor( COLORREF color )
	{
		::DeleteObject(this->curActorBr);
		this->curActorBr = ::CreateSolidBrush(color);
	}

	void BattleGround::SetMoveableColor( COLORREF color )
	{
		::DeleteObject(this->moveableBr);
		this->moveableBr = ::CreateSolidBrush(color);
	}

	void BattleGround::SetAttackableColor( COLORREF color )
	{
		::DeleteObject(this->attackableBr);
		this->attackableBr = ::CreateSolidBrush(color);
	}

	void BattleGround::SetPlaceableColor( COLORREF color )
	{
		::DeleteObject(this->placeableBr);
		this->placeableBr = ::CreateSolidBrush(color);
	}

	void BattleGround::DrawSpace(HDC dc)
	{
		RECT rt;

		rt.top = 0;
		rt.bottom = this->GetHeight();

		for(int i=0; i<=this->col; ++i)
		{
			rt.left = this->XIndexToPos(i) - this->space;
			rt.right = rt.left + this->space;

			::FillRect(dc, &rt, this->spaceBr);
		}

		rt.left = 0;
		rt.right = this->GetWidth();

		for(int i=0; i<=this->row; ++i)
		{
			rt.top = this->YIndexToPos(i) - this->space;
			rt.bottom = rt.top + this->space;

			::FillRect(dc, &rt, this->spaceBr);
		}
	}

	void BattleGround::DrawCurGrid(HDC dc)
	{
		if(this->curGrid.x<0)
			return;

		RECT rt;
		rt.left = this->XIndexToPos(this->curGrid.x) + 1;
		rt.right = rt.left + this->cellWidth - 2;
		rt.top = this->YIndexToPos(this->curGrid.y) + 1;
		rt.bottom = rt.top + this->cellHeight - 2;

		::FrameRect(dc, &rt, this->curGridBr);
	}

	void BattleGround::DrawCurActorGrid(HDC dc)
	{
		RECT dst;
		dst.left = 3 + this->XIndexToPos(this->curActorGrid.x);
		dst.top = 3 + this->YIndexToPos(this->curActorGrid.y);
		dst.right = dst.left + this->cellWidth - 6;
		dst.bottom = dst.top + this->cellHeight - 6;

		::FrameRect(dc, &dst, this->curActorBr);
	}

	void BattleGround::DrawMoveableGrid(HDC dc)
	{
		RECT dst;
		for(std::vector<Point>::iterator itr=this->grids.begin();
			itr!=this->grids.end(); ++itr)
		{
			dst.left = 3 + this->XIndexToPos(itr->x);
			dst.top = 3 + this->YIndexToPos(itr->y);
			dst.right = dst.left + this->cellWidth - 6;
			dst.bottom = dst.top + this->cellHeight - 6;

			::FrameRect(dc, &dst, this->moveableBr);
		}
	}

	void BattleGround::DrawAttackableGrid(HDC dc)
	{
		RECT dst;
		for(std::vector<Point>::iterator itr=this->grids.begin();
			itr!=this->grids.end(); ++itr)
		{
			dst.left = 3 + this->XIndexToPos(itr->x);
			dst.top = 3 + this->YIndexToPos(itr->y);
			dst.right = dst.left + this->cellWidth - 6;
			dst.bottom = dst.top + this->cellHeight - 6;

			::FrameRect(dc, &dst, this->attackableBr);
		}
	}

	void BattleGround::DrawPlaceabelGrid(HDC dc)
	{
		RECT dst;
		int gridCnt = (int)this->cells.size();
		for(int i=0; i<gridCnt; ++i)
		{
			if(this->cells[i])
				continue;

			dst.left = 3 + this->XIndexToPos(i%col);
			dst.top = 3 + this->YIndexToPos(i/col);
			dst.right = dst.left + this->cellWidth - 6;
			dst.bottom = dst.top + this->cellHeight - 6;

			::FrameRect(dc, &dst, this->placeableBr);
		}
	}

}